Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

187
Views
When updating className css transition "one step behind"

I have a form that "slides in" the different steps as cards, e.g. when moving from step 1 to step 2 the card appears from the right, and when moving back from e.g. step 3 to step 2 the card slides in from the left.

My problem is that the direction is "one step behind", it takes two clicks in one direction for the transition to catch up.

When the prev/next buttons are clicked handleActive() is called:

const handleActive = (num, text) => {
   setDirection(text)
   setActive(num)
}

An example of a card div

<div className={active === 2 ? 'card-active' : 'card-' + direction}>
<h4>Step {active}</h4>
<input className='input' type="text" name="name" id="name" placeholder='Name' />
<input className='input' type="text" name="address" id="address" placeholder='Address' />
<input className='input' type="text" name="phone" id="phone" placeholder='Phone' />
<button className='btn' type="button" onClick={() => handleActive(-1, 'from-left')}>PREV</button>
<button className='btn' type="button" onClick={() => handleActive(1, 'from-right')}>NEXT</button>
</div>

CSS:

.card-from-right {
   ...
  left: 35%;
  transition: left 800ms 0ms ease-out, height 0ms 800ms, opacity 400ms 0ms ease-in;

}

.card-from-left {
   ...
  left: 25%;
  transition: left 800ms 0ms ease-out, height 0ms 800ms, opacity 400ms 0ms ease-in;
}

.card-active {
   ...
  left: 30%;
}

I have tried async/await in the handleActive() function and useEffect, but the only thing that works is setTimeout (but that's too hacky)

const handleActive = async (num, text) => {
await setDirection(text)
await setActive(num)
}
const handleActive = async (num, text) => {
await setDirection(text)
  setTimeout(() => {
    setActive(num)
  }, 600);
}

How could I pause (and modify the DOM?) to update the classNames before running setActive()? Console.log and the source code show the correct classNames, but somehow not in time before setActive()...

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

This is a rough idea of using useEffect. You could also use num as a dependency if you need. Or you could use functions. My main point would be to put most if not all of the conditional logic inside of useEffect. (or at least be abstracted from useEffect)

useEffect(() => {
  if (direction === "to-left") {
    setActive(-1)
  } else {
   setActive(1)
  }
}, [direction]);
about 4 years ago · Juan Pablo Isaza Report

0

I was able to solve the problem with a "placeholder variable" - activeSetter (the problem with the earlier useEffect solution was that it was not triggered if the direction didn't change). Now everything happens in the right order:

  • the right className is set on non-active cards
  • the activeSetter holds the number of the next active card
  • and changes in activeSetter triggers useEffect that sets the new active card
const [activeSetter, setActiveSetter] = useState(1)

  useEffect(() => {
    setActive(activeSetter)
  }, [setActive, activeSetter])
  

  const handleActive = (num, text) => {
    setDirection(text)
    setActiveSetter(num)
  }
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!